<?php

namespace App\Http\Middleware;

use App\Http\Middleware\OpenShop\AppletAuth;
use App\Http\Middleware\OpenShop\FeishuWebAuth;
use App\Http\Middleware\OpenShop\MerchantAppAuth;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use KuafuComposer\ApiTime\Service\ApiTimeService;

/**
 * 基础接口访问日志
 */
class ApiAccessLog
{
    /**
     * 当前用户id
     * @var int
     */
    private int $userId = 0;

    // 需要返回值的白名单
    const RESPONSE_DATA_PATHS = [];

    public function handle(Request $request, Closure $next)
    {
        try {
            $resp = $next($request);
        } finally {
            $method        = $request->method();
            $uri           = $request->path();
            $ip            = $request->ip();
            $ua            = $request->header('User-Agent');
            $authorization = $request->header('Authorization');
            $shopId        = $request->header('shopId');
            $brandId       = $request->header('brandId');
            $appletToken   = $request->header('APPLET-TOKEN');
            $platformName  = $request->header('platformName') ?: AppletAuth::convertAppIdToPlatformName($request);
            $appId         = $request->header('appid');

            $params         = json_encode($request->all() ?? [], JSON_UNESCAPED_UNICODE);
            $statusCode     = $resp->getStatusCode() ?? 0;

            $msInt = (int)floor((microtime(true) - LARAVEL_START) * 1000);
            $ms    = $msInt . 'ms';

            if (in_array($request->path(), self::RESPONSE_DATA_PATHS)) {
                $response = (string)$resp->getContent();
            } else {
                $response = '';
            }

            $logContent = [
                'ip'       => $ip,
                'mt'       => $method,
                'uri'      => $uri,
                'params'   => $params,
                'ua'       => $ua,
//                'token'    => $appletToken,
                'shopId'   => $shopId,
                'brandId'  => $brandId,
                'uid'      => $this->getUserId(),
                'code'     => $statusCode,
                'rp'       => $response,
                'ms'       => $ms,
                'pName'    => $platformName,
                'appid'    => $appId,
                "auth"     => $authorization,
            ];

            $log = '';
            foreach ($logContent as $k => $c) {

                if ($c === '' || $c === null) {
                    continue;
                }

                $log .= vsprintf("[%s:%s] ", [$k, $c]);
            }

            Log::channel('apiAccess')
               ->info($log);

            // 慢接口统计
            try {
                $uri = $method . ':' . ($request->route()->uri ?? '');

                if (strtoupper($method) != 'OPTIONS') {
                    (new ApiTimeService('access'))->add($uri, LARAVEL_START);
                }
            } catch (\Exception $e) {
                Log::warning($e);
            }
        }

        return $resp;
    }

    /**
     * 获取userId
     * @return int
     */
    private function getUserId(): int
    {
        try {
            $mayBeUserId = [
                FeishuWebAuth::$userId,
                MerchantAppAuth::$userId,
                getRmsUserId(),
            ];


            foreach ($mayBeUserId as $userId) {

                if ($userId) {
                    $this->userId = $userId;

                    break;
                }
            }

        } catch (\Exception $e) {
            Log::warning($e);
        }

        return $this->userId;
    }
}
